home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
501-525
/
disk_502
/
cells
/
cellssource.lzh
/
cGrid.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-20
|
7KB
|
315 lines
/*
* CELLS An Implementation of the WireWorld cellular automata
* as described in Scientific American, Jan 1990.
*
* Copyright 1990 by Davide P. Cervone.
* You may use this code, provided this copyright notice is kept intact.
* See the CELLS.HELP file for complete information on distribution conditions.
*/
/*
* File: cGrid.c Handles grid updates and copies.
*/
#include "Cells.h"
#define BLT_COPY 0xC0
short CellSize; /* screen cell size in pixels */
short GridX,GridY; /* position of visable area */
short GridW = MAXGRIDW, GridH = MAXGRIDH; /* size of visable area */
short BoardX,BoardY, BoardW,BoardH; /* size in pixels */
/*
* SetBoardSize()
*
* Set the new cell size, and calculate the new grid and screen
* positions of the active area. Make sure we don't fall off the edge
* of the grid.
*/
void SetBoardSize(Size)
int Size;
{
short CenterX = GridX + GridW / 2,
CenterY = GridY + GridH / 2;
CellSize = Size;
GridW = (BOARDW-1) / CellSize;
GridH = (BOARDH-1) / CellSize;
BoardX = (BOARDW - CellSize * GridW) / 2;
BoardY = (BOARDH - CellSize * GridH) / 2;
BoardW = BoardX + GridW * CellSize - 1;
BoardH = BoardY + GridH * CellSize - 1;
GridX = CenterX - GridW / 2;
GridY = CenterY - GridH / 2;
if (GridX < 0) GridX = 0;
if (GridY < 0) GridY = 0;
if (GridX + GridW > MAXGRIDW) GridX = MAXGRIDW - GridW;
if (GridY + GridH > MAXGRIDH) GridY = MAXGRIDH - GridH;
}
/*
* UpdateScreen()
*
* In double buffer mode, copy the off-screen bitmap to the screen.
*/
void UpdateScreen()
{
if (DBufMode)
BltBitMapRastPort(rp->BitMap,0,0,wrp,0,0,BOARDW,BOARDH,BLT_COPY);
}
/*
* UpdateBuffer()
*
* Copy the contents of the screen area into the double buffer area
*/
void UpdateBuffer()
{
BltBitMapRastPort(wrp->BitMap,WINDOWX,WINDOWY,rp,0,0,BOARDW,BOARDH,BLT_COPY);
}
/*
* SetCell
*
* If the cell position is within the grid bounds, set the grid array
* element to the given state.
*/
void SetCell(Array,X,Y,Pen)
UBYTE Array[];
short X,Y;
int Pen;
{
if (X >= 0 && X < MAXGRIDW && Y >= 0 && Y < MAXGRIDH)
Array[X+MAXGRIDW*Y] = Pen;
}
/*
* CellColor()
*
* If the position is within the grid bounds, return the state of
* that cell, otherwise return BLANK.
*/
int CellColor(Array,X,Y)
UBYTE Array[];
short X,Y;
{
int Pen = BLANK;
if (X >= 0 && X < MAXGRIDW && Y >= 0 && Y < MAXGRIDH)
Pen = Array[X+MAXGRIDW*Y];
return(Pen);
}
/*
* ClearGrid()
*
* Set all the cells in the given array to BLANK
*/
void ClearGrid(Grid)
UBYTE Grid[];
{
register short i;
for (i=0; i<ARRAYSIZE; i++) Grid[i] = BLANK;
}
/*
* ZeroArray()
*
* Set all the cells in the given array to zero
*/
void ZeroGrid(Grid)
UBYTE Grid[];
{
register short i;
for (i=0; i<ARRAYSIZE; i++) Grid[i] = 0;
}
/*
* WipeGrid()
*
* For every cell in the give array:
* if the cell state is an electron state
* if we are updating the screen, change the screen cell color
* set the cell to the wire state
* If we are updateing the screen, do so
*/
void WipeGrid(Grid,ShowIt)
UBYTE Grid[];
int ShowIt;
{
register short X,Y;
register UBYTE Pen;
for (Y=0; Y<MAXGRIDH; Y++)
{
for (X=0; X<MAXGRIDW; X++)
{
Pen = CellColor(Grid,X,Y);
if (Pen == HEAD || Pen == TAIL)
{
if (ShowIt) ColorScreenCell(X-GridX,Y-GridY,WIRE);
SetCell(Grid,X,Y,WIRE);
}
}
}
if (ShowIt) UpdateScreen();
}
/*
* CopyGrid()
*
* Copy the contents of one grid array into another grid array
*/
void CopyGrid(OldGrid,NewGrid)
UBYTE *OldGrid,*NewGrid;
{
register short i;
for (i=0; i<ARRAYSIZE; i++) *NewGrid++ = *OldGrid++;
}
/*
* ReplaceGrid()
*
* Replace the destination grid cells by the source cells that are non-zero
* (i.e., where they are defined).
*/
void ReplaceGrid(SrcGrid,DstGrid)
UBYTE *SrcGrid,*DstGrid;
{
register short i;
for (i=0; i<ARRAYSIZE; i++)
{
if (*SrcGrid) *DstGrid = *SrcGrid;
SrcGrid++; DstGrid++;
}
}
/*
* RemoveGrid()
*
* Clear the destination cells anywhere there is a non-zero cell in the
* source grid
*/
void RemoveGrid(SrcGrid,DstGrid)
UBYTE *SrcGrid,*DstGrid;
{
register short i;
for (i=0; i<ARRAYSIZE; i++)
{
if (*SrcGrid) *DstGrid = BLANK;
SrcGrid++; DstGrid++;
}
}
/*
* UpdateGrid()
*
* Look through the active portion of the grid and for any new cells that
* have changed their state, color the new cell on the screen, and update
* the grid cells value.
*/
void UpdateGrid(Grid,NewGrid)
UBYTE Grid[],NewGrid[];
{
register UBYTE Pen;
register short i;
register short X,Y;
for (Y=0; Y<=MAXGRIDH; Y++)
{
for (X=0,i=X+MAXGRIDW*Y; X<=MAXGRIDW; X++,i++)
{
Pen = NewGrid[i];
if (Pen != Grid[i])
{
ColorScreenCell(X-GridX,Y-GridY,Pen);
Grid[i] = Pen;
}
}
}
UpdateScreen();
}
/*
* GetBounds()
*
* Initialize the bounds to outside the array, then
* for each column in the grid
* look through the column for a non-blank cell, if any
* If some column was non-blank,
* look through the columns (staring at the other side of the grid)
* for the first column containing a non-blank cell
* Starting at the top of the grid,
* search each row (within the active columns) for the first non-blank row.
* Do the same starting from the bottom of the grid.
* calculate the width and height of the active grid area.
*/
void GetBounds(Grid,x,y,w,h,blank)
UBYTE Grid[];
short *x,*y,*w,*h;
UBYTE blank;
{
register short X,Y;
register short i;
*x = MAXGRIDW; *y = MAXGRIDH; *w = *h = 0;
for (X=0; X<MAXGRIDW; X++)
for (Y=0,i=X; Y<MAXGRIDH; Y++,i+=MAXGRIDW)
if (Grid[i] != blank) {*x = X; X = MAXGRIDW; Y = MAXGRIDH;}
if (*x < MAXGRIDW)
{
for (X=MAXGRIDW-1; X>=*x; X--)
for (Y=0,i=X; Y<MAXGRIDH; Y++,i+=MAXGRIDW)
if (Grid[i] != blank) {*w = X; X = -1; Y = MAXGRIDH;}
for (Y=0; Y<MAXGRIDH; Y++)
for (X=*x,i=X+MAXGRIDW*Y; X<=*w; X++,i++)
if (Grid[i] != blank) {*y = Y; X = MAXGRIDW; Y = MAXGRIDH;}
for (Y=MAXGRIDH-1; Y>=*y; Y--)
for (X=*x,i=X+MAXGRIDW*Y; X<=*w; X++,i++)
if (Grid[i] != blank) {*h = Y; X = MAXGRIDW; Y = -1;}
*w = *w - *x + 1;
*h = *h - *y + 1;
}
}